﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Sinacor.Infra.Tools.ServiceRegistration.Business
{
    public class Type
    {
        #region Attributes

        private Data.Type _resourceAccess;
        private object locker = new object();
        
        #endregion

        #region Constructor

        public Type()
        {
            this._resourceAccess = new Data.Type();
        }

        #endregion

        #region Methods

        public List<Entity.Type> SelectType(Entity.Type entity)
        {
            return _resourceAccess.SelectType(entity, true);
        }

        public Entity.Type PersistType(Entity.Type entity)
        {
            Entity.Type type = new Entity.Type() { FullTypeName = entity.FullTypeName };
            List<Entity.Type> types = null;

            types = _resourceAccess.SelectType(type, false);

            if (types.Count == 0)
            {
                type = InsertType(entity);
            }
            else
            {
                //var selTypes = from n in types
                //       where n.FullTypeName == entity.FullTypeName
                //       select n;

                //if (selTypes.Count<Entity.Type>() > 0)
                //    type = selTypes.First();
                //else
                type = types[0];

                if (!string.IsNullOrEmpty(entity.Description) && (type.Description != entity.Description))
                    type.Description = entity.Description;
                    
                type.DateChange = entity.DateChange;
                type.DataOrigin = entity.DataOrigin;
                UpdateType(type);
            }

            return type;
        }

        public Entity.Type InsertType(Entity.Type entity)
        {
            entity.TypeId = this.GetNextTypeId();
            return _resourceAccess.InsertType(entity);
        }

        public void UpdateType(Entity.Type entity)
        {
            _resourceAccess.UpdateType(entity);
        }

        public void DeleteType(Entity.Type entity)
        {
            Data.Method methodData = new Data.Method();
            Data.Parameter parameterData = new Data.Parameter();
            List<Entity.Method> methods = null;
            List<Entity.Parameter> parameters = null;

            methods = methodData.SelectMethod(new Entity.Method() { ReturnType = new Entity.Type() { TypeId = entity.TypeId } }, false);
            parameters = parameterData.SelectParameter(new Entity.Parameter() { Type = new Entity.Type() { TypeId = entity.TypeId } }, false);

            if (methods.Count > 0 || parameters.Count > 0)
                throw new Exception("Não foi possível excluir este Tipo pois existem métodos e parâmetros vinculados a ele.");
            
            _resourceAccess.DeleteType(entity);
        }

        public int GetNextTypeId()
        {
            int nextId = 0;

            lock (locker)
            {
                nextId = _resourceAccess.GetNextTypeId();
            }

            return nextId;
        }

        #endregion
    }
}
